package com.mokairui.websocket;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * @Description com.sunshine.chat
 * @Author Mokairui
 * @Since 2022/1/11
 */
public class SimpleWebsocketChannelInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {

        ChannelPipeline pipeline = socketChannel.pipeline();

        // 基于 http 协议, 使用 http 的编码和解码
        pipeline.addLast(new HttpServerCodec());
        pipeline.addLast(new ChannelInboundHandlerAdapter() {
            @Override
            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                if (msg instanceof HttpRequest) {
                    System.out.println("http read0");
                }
                super.channelRead(ctx, msg);
            }

            @Override
            public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
                System.out.println("http" + ctx.channel().id().asLongText());
                System.out.println("http" + ctx.channel().id().asShortText());
            }
        });
        // http 是以块写, 添加 ChunkedWriteHandler 处理器
        pipeline.addLast(new ChunkedWriteHandler());

        /*
            http 数据在传输过程中是分段, httpObjectAggregator, 就是可以将多个段聚合
            这就是为什么, 当浏览器发送大量数据时, 就会发出多次 http 请求
         */
        pipeline.addLast(new HttpObjectAggregator(8192));
        /*
            对应 websocket, 他的数据是以 帧(frame) 形式传播
            WebSocketFrame 下面有六个子类
            WebSocketServerProtocolHandler 核心功能是将 http 协议升级为 ws 协议, 保持长连接
         */
        pipeline.addLast(new WebSocketServerProtocolHandler("/"));

        // 自定义的 handler, 处理业务逻辑
        pipeline.addLast(new TextWebSocketFrameHandler());

    }

}
